/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;

namespace FaceCat {
    /// <summary>
    /// 页的布局位置
    /// </summary>
    public enum FCTabPageLayout {
        /// <summary>
        /// 下方
        /// </summary>
        Bottom,
        /// <summary>
        /// 左侧
        /// </summary>
        Left,
        /// <summary>
        /// 右侧
        /// </summary>
        Right,
        /// <summary>
        /// 顶部
        /// </summary>
        Top
    }

    /// <summary>
    /// 多页夹视图
    /// </summary>
    public class FCTabView : FCDiv {
        /// <summary>
        /// 创建多页夹
        /// </summary>
        public FCTabView() {
        }

        /// <summary>
        /// 动画状态
        /// </summary>
        protected int m_animationState;

        /// <summary>
        /// 所有页
        /// </summary>
        public ArrayList<FCTabPage> m_tabPages = new ArrayList<FCTabPage>();

        /// <summary>
        /// 秒表ID
        /// </summary>
        private int m_timerID = getNewTimerID();

        public FCTabPageLayout m_layout = FCTabPageLayout.Top;

        /// <summary>
        /// 获取页的布局位置
        /// </summary>
        public virtual FCTabPageLayout getLayout()
        {
            return m_layout;
        }

        /// <summary>
        /// 设置页的布局位置
        /// </summary>
        public virtual void setLayout(FCTabPageLayout value)
        {
            m_layout = value;
        }

        public int m_selectedIndex = -1;

        /// <summary>
        /// 获取选中的索引
        /// </summary>
        public virtual int getSelectedIndex()
        {
            return m_selectedIndex;
        }

        /// <summary>
        /// 设置选中的索引
        /// </summary>
        public virtual void setSelectedIndex(int value)
        {
            int tabPageSize = m_tabPages.size();
            if (tabPageSize > 0)
            {
                if (value >= 0 && value < tabPageSize)
                {
                    m_selectedIndex = value;
                    setSelectedTabPage(m_tabPages.get(value));
                }
            }
        }

        /// <summary>
        /// 获取选中的页
        /// </summary>
        public virtual FCTabPage getSelectedTabPage()
        {
            int tabPageSize = m_tabPages.size();
            if (tabPageSize > 0)
            {
                if (m_selectedIndex >= 0 && m_selectedIndex < tabPageSize)
                {
                    return m_tabPages.get(m_selectedIndex);
                }
            }
            return null;
        }

        /// <summary>
        /// 设置选中的页
        /// </summary>
        public virtual void setSelectedTabPage(FCTabPage value)
        {
            int index = -1;
            int tabPageSize = m_tabPages.size();
            if (value != null && tabPageSize > 0)
            {
                FCTabPage oldSelectedTabPage = getSelectedTabPage();
                for (int i = 0; i < tabPageSize; i++)
                {
                    FCTabPage tabPage = m_tabPages.get(i);
                    if (tabPage == value)
                    {
                        index = i;
                        tabPage.setVisible(true);
                    }
                }
                for (int i = 0; i < tabPageSize; i++)
                {
                    FCTabPage tabPage = m_tabPages.get(i);
                    if (tabPage != value)
                    {
                        tabPage.setVisible(false);
                    }
                }
                if (index != -1)
                {
                    m_selectedIndex = index;
                }
                else
                {
                    if (tabPageSize > 0)
                    {
                        m_selectedIndex = 0;
                    }
                }
                FCTabPage newSelectedTabPage = getSelectedTabPage();
                if (oldSelectedTabPage != newSelectedTabPage)
                {
                    onSelectedTabPageChanged();
                }
                newSelectedTabPage.bringToFront();
                newSelectedTabPage.getHeaderButton().bringToFront();
            }
            else
            {
                m_selectedIndex = -1;
            }
        }

        public bool m_useAnimation;

        /// <summary>
        /// 获取是否使用动画
        /// </summary>
        public virtual bool useAnimation()
        {
            return m_useAnimation;
        }

       /// <summary>
        /// 设置是否使用动画
       /// </summary>
        public virtual void setUseAnimation(bool value)
        {
            m_useAnimation = value;
            if (m_useAnimation)
            {
                startTimer(m_timerID, 20);
            }
            else
            {
                stopTimer(m_timerID);
            }
        }

        /// <summary>
        /// 添加视图方法
        /// </summary>
        /// <param name="view">视图</param>
        public override void addView(FCView view) {
            FCTabPage tabPage = view as FCTabPage;
            if (tabPage != null) {
                tabPage.setTabView(this);
            }
            base.addView(view);
            if (tabPage != null) {
                m_tabPages.add(tabPage);
                setSelectedTabPage(tabPage);
            }
        }

        /// <summary>
        /// 清除视图
        /// </summary>
        public override void clearViews() {
            m_tabPages.clear();
            m_selectedIndex = -1;
            base.clearViews();
        }

        /// <summary>
        /// 销毁方法
        /// </summary>
        public override void delete() {
            if (!isDeleted()) {
                stopTimer(m_timerID);
            }
            base.delete();
        }

        /// <summary>
        /// 绘制移动
        /// </summary>
        public virtual void drawMoving() {
            if (m_animationState > 0) {
                bool drawing = false;
                int tabPageSize = m_tabPages.size();
                FCTabPage selectedTabPage = getSelectedTabPage();
                for (int i = 0; i < tabPageSize; i++) {
                    FCTabPage tabPage = m_tabPages.get(i);
                    if (tabPage == selectedTabPage && m_animationState == 1) {
                        continue;
                    }
                    FCButton headerButton = tabPage.getHeaderButton();
                    if (headerButton.isVisible()) {
                        int moving = headerButton.getLeft();
                        int pos = tabPage.getHeaderLocation().x;
                        if (m_layout == FCTabPageLayout.Left || m_layout == FCTabPageLayout.Right) {
                            pos = tabPage.getHeaderLocation().y;
                            moving = headerButton.getTop();
                        }
                        if (pos != moving) {
                            int relative = moving;
                            int sub = Math.Abs(pos - relative);
                            int step = 20;
                            if (m_useAnimation) {
                                if (tabPage == selectedTabPage) {
                                    if (sub > 200) {
                                        step = sub / 200 * 100;
                                    }
                                }
                                else {
                                    step = sub;
                                }
                            }
                            else {
                                step = sub;
                            }
                            if (relative != pos) {
                                if (pos > relative + step) relative += step;
                                else if (pos < relative - step) relative -= step;
                                else relative = pos;
                                if (m_layout == FCTabPageLayout.Left || m_layout == FCTabPageLayout.Right) {
                                    headerButton.setTop(relative);
                                }
                                else {
                                    headerButton.setLeft(relative);
                                }
                                drawing = true;
                            }
                        }
                    }
                }
                //绘制
                if (!drawing) {
                    if (m_animationState == 2) {
                        m_animationState = 0;
                    }
                }
                update();
                invalidate();
            }
        }

        /// <summary>
        /// 获取视图类型
        /// </summary>
        /// <returns>视图类型</returns>
        public override String getViewType() {
            return "TabView";
        }

        /// <summary>
        /// 获取事件名称列表
        /// </summary>
        /// <returns>名称列表</returns>
        public override ArrayList<String> getEventNames() {
            ArrayList<String> eventNames = base.getEventNames();
            eventNames.AddRange(new String[] { "SelectedTabPageChanged" });
            return eventNames;
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <param name="value">返回属性值</param>
        /// <param name="type">返回属性类型</param>
        public override void getAttribute(String name, ref String value, ref String type) {
            switch (name)
            {
                case "layout":
                    {
                        type = "enum:FCTabPageLayout";
                        if (getLayout() == FCTabPageLayout.Left)
                        {
                            value = "Left";
                        }
                        else if (getLayout() == FCTabPageLayout.Right)
                        {
                            value = "Right";
                        }
                        else if (getLayout() == FCTabPageLayout.Bottom)
                        {
                            value = "Bottom";
                        }
                        else
                        {
                            value = "Top";
                        }
                        break;
                    }
                case "selectedindex":
                    type = "int";
                    value = FCTran.intToStr(getSelectedIndex());
                    break;
                case "useanimation":
                    type = "bool";
                    value = FCTran.boolToStr(useAnimation());
                    break;
                default:
                    base.getAttribute(name, ref value, ref type);
                    break;
            }
        }

        /// <summary>
        /// 获取属性名称列表
        /// </summary>
        /// <returns>属性名称列表</returns>
        public override ArrayList<String> getAttributeNames() {
            ArrayList<String> attributeNames = base.getAttributeNames();
            attributeNames.AddRange(new String[] { "Layout", "SelectedIndex", "UseAnimation" });
            return attributeNames;
        }

        /// <summary>
        /// 获取多页夹列表
        /// </summary>
        /// <returns>多页夹列表</returns>
        public ArrayList<FCTabPage> getTabPages() {
            return m_tabPages;
        }

        /// <summary>
        /// 插入视图
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="view">视图</param>
        public override void insertView(int index, FCView view) {
            FCTabPage tabPage = view as FCTabPage;
            if (tabPage != null) {
                tabPage.setTabView(this);
            }
            base.addView(view);
            m_tabPages.Insert(index, tabPage);
            setSelectedTabPage(tabPage);
        }

        /// <summary>
        /// 开始拖动页头
        /// </summary>
        /// <param name="tabPage">页</param>
        public virtual void onDragTabHeaderBegin(FCTabPage tabPage) {
            m_animationState = 1;
            tabPage.getHeaderButton().bringToFront();
        }

        /// <summary>
        /// 结束拖动页头
        /// </summary>
        /// <param name="tabPage">页</param>
        public virtual void onDragTabHeaderEnd(FCTabPage tabPage) {
            if (m_animationState == 1) {
                m_animationState = 2;
                drawMoving();
            }
        }

        /// <summary>
        /// 页头拖动中
        /// </summary>
        /// <param name="tabPage">页</param>
        public virtual void onDraggingTabHeader(FCTabPage tabPage) {
            FCButton headerButton = tabPage.getHeaderButton();
            int moving = headerButton.getLeft();
            if (m_layout == FCTabPageLayout.Left || m_layout == FCTabPageLayout.Right) {
                moving = headerButton.getTop();
            }
            int tabPageSize = m_tabPages.size();
            for (int i = 0; i < tabPageSize; i++) {
                FCTabPage page = m_tabPages.get(i);
                if (page != tabPage) {
                    FCButton tpHeader = page.getHeaderButton();
                    if (tpHeader.isVisible()) {
                        int pos = page.getHeaderLocation().x;
                        int size = tpHeader.getWidth();
                        int sSize = headerButton.getWidth();
                        if (m_layout == FCTabPageLayout.Left || m_layout == FCTabPageLayout.Right) {
                            pos = page.getHeaderLocation().y;
                            size = tpHeader.getHeight();
                            sSize = headerButton.getHeight();
                        }
                        bool instead = false;
                        //向左交换
                        if (moving > pos) {
                            if (moving > pos
                                && moving < pos + size / 2) {
                                instead = true;
                            }
                        }
                        if (moving < pos) {
                            if (moving + sSize > pos + size / 2
                               && moving + sSize < pos + size) {
                                instead = true;
                            }
                        }
                        //向右交换
                        if (instead) {
                            FCPoint sLocation = tabPage.getHeaderLocation();
                            if (m_layout == FCTabPageLayout.Left || m_layout == FCTabPageLayout.Right) {
                                tabPage.setHeaderLocation(new FCPoint(tabPage.getHeaderLocation().x, pos));
                                page.setHeaderLocation(new FCPoint(page.getHeaderLocation().x, sLocation.y));
                            }
                            else {
                                tabPage.setHeaderLocation(new FCPoint(pos, tabPage.getHeaderLocation().y));
                                page.setHeaderLocation(new FCPoint(sLocation.x, page.getHeaderLocation().y));
                            }
                            int oIndex = m_tabPages.IndexOf(tabPage);
                            int nIndex = m_tabPages.IndexOf(page);
                            m_tabPages.set(oIndex, page);
                            m_tabPages.set(nIndex, tabPage);
                            m_selectedIndex = nIndex;
                            break;
                        }
                    }
                }
            }
            drawMoving();
        }

        /// <summary>
        /// 添加视图方法
        /// </summary>
        public override void onLoad() {
            base.onLoad();
            if (m_useAnimation) {
                startTimer(m_timerID, 20);
            }
            else {
                stopTimer(m_timerID);
            }
        }

        /// <summary>
        /// 页改变方法
        /// </summary>
        public virtual void onSelectedTabPageChanged() {
            callEvents("onselectedtabpagechanged");
        }

        /// <summary>
        /// 秒表方法
        /// </summary>
        /// <param name="timerID">秒表ID</param>
        public override void onTimer(int timerID) {
            base.onTimer(timerID);
            if (m_timerID == timerID) {
                drawMoving();
            }
        }

        /// <summary>
        /// 移除视图
        /// </summary>
        /// <param name="view">视图</param>
        public override void removeView(FCView view) {
            FCTabPage tabPage = view as FCTabPage;
            if (tabPage != null) {
                int tabPageSize = m_tabPages.size();
                if (tabPageSize > 0) {
                    FCTabPage selectedPage = getSelectedTabPage();
                    if (selectedPage == tabPage) {
                        if (m_selectedIndex > 0) {
                            if (m_selectedIndex < tabPageSize - 1) {
                                selectedPage = m_tabPages.get(m_selectedIndex + 1);
                            }
                            else {
                                selectedPage = m_tabPages.get(m_selectedIndex - 1);
                            }
                        }
                        else {
                            if (tabPageSize > 1) {
                                selectedPage = m_tabPages.get(m_selectedIndex + 1);
                            }
                        }
                    }
                    m_tabPages.remove(tabPage);
                    base.removeView(tabPage.getHeaderButton());
                    base.removeView(tabPage);
                    tabPage.setTabView(null);
                    setSelectedTabPage(selectedPage);
                }
            }
            else {
                base.removeView(view);
            }
        }

        /// <summary>
        /// 设置属性
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <param name="value">属性值</param>
        public override void setAttribute(String name, String value)
        {
            switch (name)
            {
                case "layout":
                    {
                        value = value.ToLower();
                        if (value == "left")
                        {
                            setLayout(FCTabPageLayout.Left);
                        }
                        else if (value == "top")
                        {
                            setLayout(FCTabPageLayout.Top);
                        }
                        else if (value == "right")
                        {
                            setLayout(FCTabPageLayout.Right);
                        }
                        else if (value == "bottom")
                        {
                            setLayout(FCTabPageLayout.Bottom);
                        }
                        break;
                    }
                case "selectedindex":
                    setSelectedIndex(FCTran.strToInt(value));
                    break;
                case "useanimation":
                    setUseAnimation(FCTran.strToBool(value));
                    break;
                default:
                    base.setAttribute(name, value);
                    break;
            }
        }

        /// <summary>
        /// 多页夹的样式
        /// </summary>
        public virtual void tabStyle(int layoutStyle, ref FCRect bounds, ref FCPadding padding,
        ref FCPadding margin, int left, int top, int width, int height,
         int tw, int th, ref FCPoint headerLocation) {
            switch (layoutStyle) {
                case 0:
                    bounds.left = padding.left;
                    bounds.top = padding.top;
                    bounds.right = width;
                    bounds.bottom = height - th;
                    headerLocation.x = left;
                    headerLocation.y = height - th;
                    break;
                case 1:
                    bounds.left = tw;
                    bounds.top = padding.top;
                    bounds.right = width;
                    bounds.bottom = height;
                    headerLocation.x = padding.left;
                    headerLocation.y = top;
                    break;
                case 2:
                    bounds.left = padding.left;
                    bounds.top = padding.top;
                    bounds.right = width - tw;
                    bounds.bottom = height;
                    headerLocation.x = width - tw;
                    headerLocation.y = top;
                    break;
                case 3:
                    bounds.left = padding.left;
                    bounds.top = th;
                    bounds.right = width;
                    bounds.bottom = height;
                    headerLocation.x = left;
                    headerLocation.y = padding.top;
                    break;
            }
        }

        /// <summary>
        /// 重新布局
        /// </summary>
        public override void update()
        {
            if (m_native != null && !m_native.m_lockUpdate)
            {
                base.update();
                FCPadding padding = getPadding(); ;
                int left = padding.left, top = padding.top;
                int width = getWidth() - padding.left - padding.right;
                int height = getHeight() - padding.top - padding.bottom;
                int tabPageSize = m_tabPages.size();
                for (int i = 0; i < tabPageSize; i++)
                {
                    FCTabPage tabPage = m_tabPages.get(i);
                    FCButton headerButton = tabPage.getHeaderButton();
                    if (headerButton.isVisible())
                    {
                        FCPadding margin = headerButton.getMargin();
                        int tw = headerButton.getWidth() + margin.left + margin.right;
                        int th = headerButton.getHeight() + margin.top + margin.bottom;
                        FCRect bounds = new FCRect();
                        FCPoint headerLocation = new FCPoint();
                        int layout = 0;
                        switch (m_layout)
                        {
                            case FCTabPageLayout.Bottom:
                                layout = 0;
                                break;
                            case FCTabPageLayout.Left:
                                layout = 1;
                                break;
                            case FCTabPageLayout.Right:
                                layout = 2;
                                break;
                            case FCTabPageLayout.Top:
                                layout = 3;
                                break;
                        }
                        tabStyle(layout, ref bounds, ref padding,
                        ref margin, left, top, width, height,
                         tw, th, ref headerLocation);
                        tabPage.setBounds(bounds);
                        tabPage.setHeaderLocation(headerLocation);
                        if (!m_useAnimation)
                        {
                            tabPage.getHeaderButton().setLocation(headerLocation);
                        }
                        if (m_animationState > 0)
                        {
                            if (m_layout == FCTabPageLayout.Left || m_layout == FCTabPageLayout.Right)
                            {
                                headerLocation.y = headerButton.getTop();
                            }
                            else if (m_layout == FCTabPageLayout.Bottom || m_layout == FCTabPageLayout.Top)
                            {
                                headerLocation.x = headerButton.getLeft();
                            }
                        }
                        headerButton.setLocation(headerLocation);
                        left += tw;
                        top += th;
                    }
                    else
                    {
                        tabPage.setVisible(false);
                    }
                }
            }
        }
    }
}
